﻿
using Ops.Mpc.Collections;
using System.Collections.Generic;
using System.Windows.Markup;
namespace Ops.Mpc.States
{
    [ContentProperty("StateActions")]
    public class CompositeStateAction : StateAction
    {
        #region Fields & Properties
        private NamedItemCollection<StateAction> _stateActions = new NamedItemCollection<StateAction>();
        private Queue<StateActionContext> _stateActionQueue = new Queue<StateActionContext>();

        public NamedItemCollection<StateAction> StateActions
        {
            get
            {
                return this._stateActions;
            }
        }
        #endregion

        #region Methods

        public override void Start()
        {
            foreach (IStateAction iStateAction in this._stateActions)
            {
                iStateAction.Controller = this.Controller;
                iStateAction.Start();
            }

            base.Start();
        }

        protected override void OnExecute(object context)
        {
            base.OnExecute(context);
            this._stateActionQueue.Clear();

            for(int index = 0; index < this._stateActions.Count; index++)
            {
                this._stateActionQueue.Enqueue(new StateActionContext(this._stateActions[index],context));
            }

            this.ExecuteEnqueuedStateActions();

        }

        protected void ExecuteEnqueuedStateActions()
        {
            if (!this.Controller.IsStopped)
            {
                StateActionContext tuple = this._stateActionQueue.Dequeue();
                StateAction stateAction = tuple.StateAction;
                stateAction.Execute(tuple.Context, new ActionResultCallback(OnExecuteEnqueuedStateActionCompleted));
            }
        }

        protected void OnExecuteEnqueuedStateActionCompleted(ActionResult stateActionResult)
        {
           
            bool hasLeftState = this.Controller.CurrentState == null ||  this != this.Controller.CurrentState.GetStateAction(this.ItemName, false);

            if (!this.Controller.IsStopped && !hasLeftState && stateActionResult.Successful && this._stateActionQueue.Count > 0)
            {
                if (!this.Controller.Presenter.Dispatcher.CheckAccess())
                {
                    this.Controller.Presenter.Dispatcher.BeginInvoke(delegate { this.ExecuteEnqueuedStateActions(); });
                    return;
                }

                this.ExecuteEnqueuedStateActions();
            }
            else
                this.Finish(stateActionResult);


        }
        #endregion
    }
}
